from operator import methodcaller
from time import sleep
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
import logging

from utils.yml_Util import yml_Util

logger = logging.getLogger()


def cellphone_init(yml_url):
    yml_info = yml_Util.reader(yml_url)
    logger.info(yml_info)
    return yml_info


class appium_Util:

    def __init__(self, yml_url='data/cellphone.yml'):
        # 初始化 Webdriver（面向手机App）
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', dict(cellphone_init(yml_url)))

    # 元素定位
    def locator(self, find_command, name):
        try:
            logger.info('执行 locator 定位: 查询命令=' + find_command + '   路径=' + name)
            return self.driver.find_element(find_command, name)
        except Exception as e:
            logger.error(msg='locator 异常:   %s' % str(type(e)) + '::%s' % e)
            return None

    # 获取元素文字内容
    def get_text(self, find_command, name):
        try:
            logger.info('执行 get_text 方法:    查询命令=' + find_command + '   路径=' + name)
            return self.driver.find_element(find_command, name).text
        except Exception as e:
            logger.error(msg='get_text 异常:%s' % str(type(e)) + '::%s' % e)
            return None

    # 元素点击
    def click(self, find_command, name):
        try:
            logger.info('执行 click 方法:   查询命令=' + find_command + '  路径=' + name)
            sleep(1)
            # action = ActionChains(self.driver)
            # action.click(self.driver.find_element(find_command, name))
            # action.perform()
            ele = self.driver.find_element(find_command, name)
            ele.click()
            sleep(1)
        except Exception as e:
            logger.error(msg='click 异常:%s' % str(type(e)) + '::%s' % e)
        # for request in self.driver.requests:
        #     print(type(request.response.body))
        #     print(str(request.response.body, 'UTF-8'))

    # 元素输入内容
    def input(self, find_command, name, value=None):
        try:
            logger.info('执行 input 方法:   查询命令=' + find_command + '   路径=' + name + '   输入值:' + str(value))
            sleep(2)
            ele = self.driver.find_element(find_command, name)
            ele.click()
            ele.send_keys(value)
        except Exception as e:
            logger.error(msg='input 异常: %s' % str(type(e)) + '::%s' % e)

    # 长按鼠标
    def long_press(self, find_command, name, seconds):
        try:
            action = TouchAction(self.driver)
            action.long_press(el=self.driver.find_element(find_command, name), duration=seconds)
            action.perform()
        except Exception as e:
            logger.error(msg='long_press 异常:    %s' % str(type(e)) + '::%s' % e)

    # 移动
    def move_by_offset(self, find_command, name, value='0,0'):
        try:
            position = value.split(',')
            logger.info('执行 move_by_offset 方法:  查询命令=' + find_command + ' 路径=' + name + '  X轴位移:' + position[0]
                        + 'Y轴位移:' + position[1])
            sleep(1)
            action = TouchAction(self.driver)
            action.move_to(self.driver.find_element(find_command, name), x=int(position[0]), y=int(position[1]))
            action.perform()
        except Exception as e:
            logger.error(msg='move_by_offset 异常:    %s' % str(type(e)) + '::%s' % e)

    # 松开鼠标
    def release(self):
        action = TouchAction(self.driver)
        action.release()
        action.perform()

    # 退出
    def quit(self):
        try:
            logger.info('执行 quit 方法')
            self.driver.quit()
        except Exception as e:
            logger.error(msg='quit 异常:  %s' % str(type(e)) + '::%s' % e)

    # selenium js执行器
    def js_execute(self, JS):
        try:
            logger.info('执行 js_execute 方法:  JS代码=' + JS)
            sleep(1)
            print(self.driver.execute_script(JS))
        except Exception as e:
            logger.error(msg='js_execute 异常:    %s' % str(type(e)) + '::%s' % e)

    def remove_attribute(self, elem, attribute):
        try:
            logger.info('执行 remove_attribute 方法: 删除' + elem + '的' + attribute)
            sleep(1)
            print(self.driver.execute_script('arguments[0].removeAttribute(arguments[1])', elem, attribute))
        except Exception as e:
            logger.error(msg='remove_attribute 异常:  %s' % str(type(e)) + '::%s' % e)

    def set_attribute(self, elem, attribute, value):
        logger.info('执行 set_attribute 方法:   为' + str(elem) + '添加' + attribute + '属性，值为：' + value)
        self.driver.execute_script('arguments[0].setAttribute(arguments[1],arguments[2])', elem, attribute, value)

    def methodcaller(self, method_name, **kwargs):
        try:
            for key in list(kwargs.keys()):
                if kwargs[key] is None:
                    del kwargs[key]
        except Exception as e:
            logger.error(msg='methodcaller 异常:  %s' % str(type(e)) + '::%s' % e)
        finally:
            caller = methodcaller(str(method_name), **kwargs)
            caller(self)

    def screenshot(self):
        png = self.driver.get_screenshot_as_png()
        return png
